package cn.fanyamin.dao.hibernate;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.fanyamin.ICRUDL;

/**
 * @author walter
 *
 * @param <T>
 * @param <PK>
 */
public class CRUDLDao<T, PK extends Serializable> extends HibernateDaoSupport
        implements ICRUDL<T, PK> {

    private Class<T> persistentClass;

    public CRUDLDao(Class<T> type) {
        this.persistentClass = type;
    }

    @Override
    public PK create(T obj) {
        return (PK) super.getHibernateTemplate().save(obj);
    }

    @Override
    public T retrieve(PK id) {
        return (T) super.getHibernateTemplate().get(this.persistentClass, id);
    }

    @Override
    public void update(T obj) {
        super.getHibernateTemplate().update(obj);
    }

    @Override
    public void delete(PK id) {
        super.getHibernateTemplate().delete(this.retrieve(id));
    }

    @Override
    public int count() {
        return ((Long)(super.getHibernateTemplate().find("select count(*) from " + this.persistentClass.getSimpleName()).iterator().next())).intValue();
    }

    @Override
    public Collection<T> list() {
        return super.getHibernateTemplate().loadAll(this.persistentClass);
    }

    @Override
    public Collection<T> list(int pageNum, int pageSize) {
        
        final int n0 = pageNum * pageSize;
        final int n1 = (pageNum + 1)* pageSize -1;
        HibernateCallback callback = new HibernateCallback() {

            public Object doInHibernate(Session session)
                    throws HibernateException, SQLException {
                Query query = session.createQuery("from " + persistentClass.getSimpleName());
                query.setFirstResult(n0);
                query.setMaxResults(n1);
                return query.list();
            }
            
        };
        
        return (Collection<T>)super.getHibernateTemplate().execute(callback);
    }

}
